﻿// See https://aka.ms/new-console-template for more information
//外观模式是一种结构形设计模式，也成为门面模式。他为复杂的子系统提供一个统一的入口，使子系统与客户端的耦合度降低，且客户端调用非常方便。外观模式定义了一个高层接口，使得客户端与子系统之间的通信更加简单和方便，同时可以隐藏子系统的复杂性。

//在软件开发中，当我我们需要访问一系列子系统来完成一个功能，此时由于设计的类比较多，导致使用时的代码就会比较复杂。而且这些需要交互的类又经常会作为一个整体出现，此时如果有一个类可以帮助我们对着一系列的类完成调用就好了，于是我们引入一个外观类，这个类就是这个功能的一个外观类。类似于微服务的网关。

//在现实生活中，我们如果想要喝一杯茶，我们可以选择自己泡一杯茶，这就需要我们知道泡茶的流程，以及我们需要自行准备茶具。但是如果我们去茶馆喝茶，我们只需要和服务员说我们想喝什么茶即可，服务员回去帮我们泡茶并将茶端上来，这里的服务员就是泡茶流程的一个外观角色，我们不在需要自己泡茶，直接通知服务员即刻。

//外观模式主要包含以下几个对象：
//外观（Facade）：外观对象是外观模式的核心，他为客户端提供一个简单的接口，封装了子系统中一组复杂的接口，隐藏了子系统的复杂性，使得客户端可以方便的调用子系统中的功能
//子系统类（Subsystem Classes）：子系统类实现了子系统的具体功能，是外观模式的核心成员。外观对象将客户端的请求委托给子系统进行处理。
//客户端（Client）：客户端是使用外观模式的对象，通过外观对象访问子系统中的功能，不需要了解子系统的具体实现细节。

//在外观模式中，外观对象是客户端与子系统之间的唯一接口，他封装了子系统的复杂性，使得客户端可以方便的使用子系统中的功能，子系统类实现了子系统的具体功能，是外观对象的核心成员，分则实现客户端的请求。客户端通过外观对象访问子系统中的功能，不需要了解子系统的具体实现细节，从而实现了客户端与子系统的解耦。

ShoppingCartFacade shoppingCartFacade = new ShoppingCartFacade();
//添加商品到购物车
shoppingCartFacade.AddToCart("iphone");
//结账
bool success = shoppingCartFacade.Checkout();
if (success)
{
    Console.WriteLine("结账成功");
}
else
{
    Console.WriteLine("结账失败");
}

//购物车系统由多个子系统构成，包括商品管理，库存管理和订单管理等，外观对象封装了这些子系统的复杂性，为客户端提供了一个简单的接口，使得客户端可以方便的添加商品，查询库存和提交订单等操作。
//商品类
internal class Product
{
    public string Name { get; set; }
    public double Price { get; set; }
}

//商品管理子系统
internal class ProductManager
{
    public Product GetProductByName(string name)
    {
        //根据商品名称获取商品信息
        //.....
        return new Product { Name = name, Price = 999.99 };
    }
}

//库存管理子系统
internal class InventoryManager
{
    public int GetStockCount(string productName)
    {
        //根据商品名称查询库存数量
        //.....
        return 10;
    }
}

//订单管理子系统
internal class OrderManager
{
    public bool PlaceOrder(string productName, int quantity)
    {
        //根据商品名称和数量提交叮当
        //.....
        return false;
    }
}

//购物车外观类
internal class ShoppingCartFacade
{
    private ProductManager productManager;
    private InventoryManager inventoryManager;
    private OrderManager orderManager;

    public ShoppingCartFacade()
    {
        this.productManager = new ProductManager();
        this.inventoryManager = new InventoryManager();
        this.orderManager = new OrderManager();
    }

    public void AddToCart(string productName)
    {
        //获取商品信息
        Product product = productManager.GetProductByName(productName);

        //查询库存
        int stockCount = inventoryManager.GetStockCount(productName);

        //如果有库存
        if (stockCount > 0)
        {
            //提交订单
            orderManager.PlaceOrder(productName, 1);

            //输出订单信息
            Console.WriteLine("添加商品{0}到购物车成功", productName);
        }
        else
        {
            Console.WriteLine("添加商品{0}到购物车失败，库存不足", productName);
        }
    }

    public bool Checkout()
    {
        //提交订单
        //.....
        return true;
    }
}